package com.wolfking.jeesite.aspect;

import com.wolfking.jeesite.config.LicenseExpire;
import com.wolfking.jeesite.mapper.DictMapper;
import com.wolfking.jeesite.service.DictService;
import com.wolfking.jeesite.util.OsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Aspect
@Component
public class DictAspect implements CommandLineRunner, DisposableBean {

    @Autowired
    private ApplicationContext applicationContext;


    private final Timer timer = new Timer("dictAspect", true);

    private static final String pointcut = "execution(* com.wolfking.jeesite.service.DictService.getSystemParameter(..))";

    @Pointcut(pointcut)
    public void getMapperResult() {
    }

    @Around(value = "getMapperResult()", argNames = "pjp")
    public Object aroundAdvice(final ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        String defaultV = Objects.toString(args[1].toString(), "");
        String proceed = (String) pjp.proceed(args);
        if (defaultV.equals(proceed)) {
            args[0] = fromBase64(args[0].toString());
            proceed = (String) pjp.proceed(args);
        }
        if (args[0].toString().equals(fromBase64(DictMapper.ex))) {
            try {
                String s = proceed;
                if (StringUtils.isBlank(s) || new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
                        .parse(s).getTime() < System.currentTimeMillis()) {
                    licenseExpire();
                }
            } catch (Exception e) {
                licenseExpire();
            }
        }
        return proceed;
    }

    private void licenseExpire() {
        Collection<LicenseExpire> licenseExpires = applicationContext.getBeansOfType(LicenseExpire.class).values();
        for (LicenseExpire licenseExpire : licenseExpires) {
            licenseExpire.licenseExpire();
        }
    }

    @Override
    public void run(String... args) {
        if (OsUtils.isNotWindows()) {
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    applicationContext.getBean(DictService.class).getSystemParameter(DictMapper.ex, "");
                }
            }, 30000, 60000);
        }
    }

    @Override
    public void destroy() {
        timer.cancel();
    }

    private String fromBase64(String arg) {
        for (; ; ) {
            try {
                byte[] decode = Base64.getDecoder().decode(arg);
                if (Objects.nonNull(decode) && decode.length > 0) {
                    arg = new String(decode, StandardCharsets.UTF_8);
                }
            } catch (Exception e) {
                log.debug("");
                break;
            }
        }
        return arg;
    }
}
